package com.kwq.designPattern.generate.prototype;

import com.google.gson.Gson;
import lombok.Data;
import java.io.*;

/**
 * @author kangwanqiang
 * @date 2021/2/4
 * @description 深克隆的序列化方式实现
 */
@Data
public class DeepClone implements Serializable, Cloneable {
    String name;
    Integer age;
    ConcretePrototype concretePrototype;

    @Override
    public String toString() {
        return "DeepClone{" + "name='" + name + '\'' + ", age=" + age
                + ", concretePrototype=" + concretePrototype + '}';
    }

    public DeepClone(String name, Integer age,
            ConcretePrototype concretePrototype) {
        this.name = name;
        this.age = age;
        this.concretePrototype = concretePrototype;
    }

    @Override
    protected Object clone() {
        /**
         * gson序列化方式实现深克隆
         * Gson gson = new Gson();
         * String json = gson.toJson(this);
         * return gson.fromJson(json, this.getClass());
         */
        // 原生序列化方式实现深克隆
        ByteArrayOutputStream byteArrayOutputStream = null;
        ObjectOutputStream objectOutputStream = null;
        ByteArrayInputStream byteArrayInputStream = null;
        ObjectInputStream objectInputStream = null;
        DeepClone deepClone = null;
        try {

            byteArrayOutputStream = new ByteArrayOutputStream();
            objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
            objectOutputStream.writeObject(this);

            byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
            objectInputStream = new ObjectInputStream(byteArrayInputStream);

            deepClone = (DeepClone) objectInputStream.readObject();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {


                if (byteArrayOutputStream != null) {
                    byteArrayOutputStream.close();
                }
                if (objectOutputStream != null) {
                    objectOutputStream.close();
                }
                if (byteArrayInputStream != null) {
                    byteArrayInputStream.close();
                }
                if (objectInputStream != null) {
                    objectInputStream.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        return deepClone;
    }
}
